import os, sys, subprocess, getopt, re, time, signal;
from subprocess import Popen, PIPE, STDOUT;
   

from config import *    # loads global variables and helper function from default_vars.py

#
#    PROJECT 1B - GRADING APPLICATION - Helper Function
#
#    (this file contains functions used by main.py with allow the main
#        script to be more readable)


# returns all directories in 'directory' whose name is 9 digits (i.e. SID number)
def listdirs(folder):
	dirs = []
	for d in (os.listdir(folder)):
        # only return directories that have a 9-digit name
		if (os.path.isdir(os.path.join(folder, d)) and re.match("^[0-9]{9}$",d)):
			dirs.append(d)
	return dirs

# returns a readable time format
# PARAMETER:	seconds	=> time in seconds
# RETURNS:	time as a string in hours, minutes, and seconds
def GetInHMS(seconds):
	hours = seconds / 3600
	seconds -= 3600*hours
	minutes = seconds / 60
	seconds -= 60*minutes
	if hours == 0:
		if minutes == 0:
			return "%02d secs" % (seconds)
		else:
			return "%02d mins %02d secs" % (minutes, seconds)
			

# construct string for MyUCLA Gradebook TSV file entry and write to file
# format: sid <tab> name <tab> score <tab> [comment]
def write_gradebook(fd, sid, pt_array, comments):
	try:
		out_str = str(sid)
		total = 0
		for idx in range(0,len(pt_array)):
			out_str += "\t" + str(pt_array[idx])
			total += pt_array[idx]
		out_str += "\t" + str(total) + "\t" + str(comments) + "\n"  
		fd.write(out_str)
		fd.flush()
	except OSError, e:
		print >>sys.stderr, "Unable to store gradebook entry for SID: " + sid
		exit()
	return 0


# Parse Result
def parse_returning_set(string):
	ret_set = set()
	tmp_set = set(string.splitlines())
	for line in tmp_set:
		parsed_line = re.sub("Bruinbase> ","",line).strip()
		if(len(parsed_line) > 0):
			ret_set.add(parsed_line)
			
	return ret_set
	
def parse_processing_line(string):
	process_time = -1.0
	pageread = -1
	
	matchgroup = re.search("[0-9].[0-9]+",string)
	if(matchgroup):
		process_time = float(matchgroup.group())

	matchgroup = re.search("Read [0-9]+ pages",string)
	if(matchgroup):
		page_match = re.search("[0-9]+",matchgroup.group()) 
		pageread = int(page_match.group())
		
		
	return (process_time,pageread)


# Run Command with a Timeout value
def runCmd(cmd, timeout):
	'''
	Will execute a command, read the output and return it back.

	@param cmd: command to execute
	@param timeout: process timeout in seconds
	@return: a tuple of three: first stdout, then stderr, then exit code
	@raise OSError: on missing command or if a timeout was reached
	'''

	ph_out = None # process output
	ph_err = None # stderr
	ph_ret = None # return code

	p = subprocess.Popen(cmd, shell=True,
                	     stdout=subprocess.PIPE,
                	     stderr=subprocess.PIPE,
			     bufsize=0)
	# if timeout is not set wait for process to complete
	if not timeout:
	    ph_ret = p.wait()
	else:
	    fin_time = time.time() + timeout
	    while p.poll() == None and fin_time > time.time():
        	time.sleep(1)

	    # if timeout reached, raise an exception
		if fin_time < time.time():
        	# starting 2.6 subprocess has a kill() method which is preferable
			#p.kill()
			os.kill(p.pid, signal.SIGKILL)
			ph_out = 0
			ph_err = "TIME OUT"
			ph_ret = 1                                            
			return (1, ph_out, ph_err, ph_ret)

	ph_ret = p.returncode
	ph_out, ph_err = p.communicate()

	return (0, ph_out, ph_err, ph_ret) 
	
	
	


